/*
 * Copyright 2010 Thedwick, LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package com.thedwick.jdbcGrabber;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;

import com.thedwick.jdbcGrabber.sink.SQLSink;
import com.thedwick.jdbcGrabber.statement.gbCallableStatement;
import com.thedwick.jdbcGrabber.statement.gbPreparedStatement;
import com.thedwick.jdbcGrabber.statement.gbStatement;

public class gbConnection implements Connection {
	private final Connection underlying;
	private final SQLSink sink;
	public gbConnection(SQLSink sink, Connection underlying) {
		this.sink = sink;
		this.underlying = underlying;
	}

	@Override
	public void clearWarnings() throws SQLException {
		this.underlying.clearWarnings();
	}

	@Override
	public void close() throws SQLException {
		this.underlying.close();

	}

	@Override
	public void commit() throws SQLException {
		this.underlying.commit();
	}

	@Override
	public Array createArrayOf(String arg0, Object[] arg1) throws SQLException {
		return this.underlying.createArrayOf(arg0,arg1);
	}

	@Override
	public Blob createBlob() throws SQLException {
		return this.underlying.createBlob();
	}

	@Override
	public Clob createClob() throws SQLException {
		return this.underlying.createClob();
	}

	@Override
	public NClob createNClob() throws SQLException {
		return this.underlying.createNClob();
	}

	@Override
	public SQLXML createSQLXML() throws SQLException {
		return this.underlying.createSQLXML();
	}

	@Override
	public Statement createStatement() throws SQLException {
		Statement stmt = this.underlying.createStatement();
		return new gbStatement(stmt, sink);
	}

	@Override
	public Statement createStatement(int resultSetType, int resultSetConcurrency)
			throws SQLException {
		Statement stmt = this.underlying.createStatement(resultSetType, resultSetConcurrency);
		return new gbStatement(stmt, sink);
	}

	@Override
	public Statement createStatement(int resultSetType,
			int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		Statement stmt = this.underlying.createStatement(resultSetType, resultSetConcurrency,
				resultSetHoldability);
		return new gbStatement(stmt, sink);

	}

	@Override
	public Struct createStruct(String arg0, Object[] arg1) throws SQLException {
		return this.underlying.createStruct(arg0, arg1);
	}

	@Override
	public boolean getAutoCommit() throws SQLException {
		return this.underlying.getAutoCommit();
	}

	@Override
	public String getCatalog() throws SQLException {
		return this.underlying.getCatalog();
	}

	@Override
	public Properties getClientInfo() throws SQLException {
		return this.underlying.getClientInfo();
	}

	@Override
	public String getClientInfo(String arg0) throws SQLException {
		return this.underlying.getClientInfo(arg0);
	}

	@Override
	public int getHoldability() throws SQLException {
		return this.underlying.getHoldability();
	}

	@Override
	public DatabaseMetaData getMetaData() throws SQLException {
		return this.underlying.getMetaData();
	}

	@Override
	public int getTransactionIsolation() throws SQLException {
		return this.underlying.getTransactionIsolation();
	}

	@Override
	public Map<String, Class<?>> getTypeMap() throws SQLException {
		return this.underlying.getTypeMap();
	}

	@Override
	public SQLWarning getWarnings() throws SQLException {
		return this.underlying.getWarnings();
	}

	@Override
	public boolean isClosed() throws SQLException {
		return this.underlying.isClosed();
	}

	@Override
	public boolean isReadOnly() throws SQLException {
		return this.underlying.isReadOnly();
	}

	@Override
	public boolean isValid(int arg0) throws SQLException {
		return this.underlying.isValid(arg0);
	}

	@Override
	public String nativeSQL(String sql) throws SQLException {
		return this.underlying.nativeSQL(sql);
	}

	@Override
	public CallableStatement prepareCall(String sql) throws SQLException {
		CallableStatement stmt = this.underlying.prepareCall(sql);
		return new gbCallableStatement(stmt, sink, sql);
	}

	@Override
	public CallableStatement prepareCall(String sql, int resultSetType,
			int resultSetConcurrency) throws SQLException {
		CallableStatement stmt = this.underlying.prepareCall(sql, resultSetType, resultSetConcurrency);
		return new gbCallableStatement(stmt, sink, sql);
	}

	@Override
	public CallableStatement prepareCall(String sql, int resultSetType,
			int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		CallableStatement stmt = this.underlying.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
		return new gbCallableStatement(stmt, sink, sql);
	}

	@Override
	public PreparedStatement prepareStatement(String sql) throws SQLException {
		PreparedStatement stmt = this.underlying.prepareStatement(sql);
		return new gbPreparedStatement(stmt, sink, sql);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
			throws SQLException {
		PreparedStatement stmt = this.underlying.prepareStatement(sql,autoGeneratedKeys);
		return new gbPreparedStatement(stmt, sink, sql);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
			throws SQLException {
		PreparedStatement stmt = underlying.prepareStatement(sql, columnIndexes);
		return new gbPreparedStatement(stmt, sink, sql);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, String[] columnNames)
			throws SQLException {
		PreparedStatement stmt = this.underlying.prepareStatement(sql, columnNames);
		return new gbPreparedStatement(stmt, sink, sql);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int resultSetType,
			int resultSetConcurrency) throws SQLException {
		PreparedStatement stmt = this.underlying.prepareStatement(sql, resultSetType, resultSetConcurrency);
		return new gbPreparedStatement(stmt, sink, sql);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int resultSetType,
			int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		PreparedStatement stmt = this.underlying.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
		return new gbPreparedStatement(stmt, sink, sql);
	}

	@Override
	public void releaseSavepoint(Savepoint savepoint) throws SQLException {
		this.underlying.releaseSavepoint(savepoint);
	}

	@Override
	public void rollback() throws SQLException {
		this.underlying.rollback();
	}

	@Override
	public void rollback(Savepoint savepoint) throws SQLException {
		this.underlying.rollback(savepoint);
	}

	@Override
	public void setAutoCommit(boolean autoCommit) throws SQLException {
		this.underlying.setAutoCommit(autoCommit);
	}

	@Override
	public void setCatalog(String catalog) throws SQLException {
		this.underlying.setCatalog(catalog);
	}

	@Override
	public void setClientInfo(Properties arg0) throws SQLClientInfoException {
		this.underlying.setClientInfo(arg0);
	}

	@Override
	public void setClientInfo(String arg0, String arg1)
			throws SQLClientInfoException {
		this.underlying.setClientInfo(arg0, arg1);
	}

	@Override
	public void setHoldability(int holdability) throws SQLException {
		this.underlying.setHoldability(holdability);
	}

	@Override
	public void setReadOnly(boolean readOnly) throws SQLException {
		this.underlying.setReadOnly(readOnly);
	}

	@Override
	public Savepoint setSavepoint() throws SQLException {
		return this.underlying.setSavepoint();
	}

	@Override
	public Savepoint setSavepoint(String name) throws SQLException {
		return this.underlying.setSavepoint(name);
	}

	@Override
	public void setTransactionIsolation(int level) throws SQLException {
		this.underlying.setTransactionIsolation(level);
	}

	@Override
	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
		this.underlying.setTypeMap(map);
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		return this.underlying.isWrapperFor(iface);
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException {
		return this.underlying.unwrap(iface);
	}

	public Connection getUnderlying() {
		return this.underlying;
	}

}
